﻿// <copyright>
// Copyright (c) 2008 - 2009, Microsoft, All Rights Reserved
// </copyright>
//
// Licensed under the Microsoft Public License (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at 
//
// http://www.opensource.org/licenses/ms-pl.html

namespace LiveLabs.Logging
{
    using System;
    using System.Globalization;
    using System.Text;
    using System.Threading;
    using LiveLabs.Logging.Resources;
    using LiveLabs.Logging.Util;

    /// <summary>
    /// Contains the default formatters
    /// </summary>
    public static class DefaultFormatters
    {
        private static MessageFormatter defaultMessageFormatter;

        private static ExceptionFormatter defaultExceptionFormatter;

        /// <summary>
        /// Initializes static members of the DefaultFormatters class.
        /// </summary>
        static DefaultFormatters()
        {
            Reset();
        }

        /// <summary>
        /// Gets or sets the default formatter to use for user messages
        /// </summary>
        public static MessageFormatter Message
        {
            get
            {
                return defaultMessageFormatter;
            }

            set
            {
                if (value == null)
                {
                    value = _DefaultMessageFormatter;
                }

                defaultMessageFormatter = value;
            }
        }

        /// <summary>
        /// Gets or sets the default formatter to use for exceptions.
        /// </summary>
        public static ExceptionFormatter Exception
        {
            get
            {
                return defaultExceptionFormatter;
            }

            set
            {
                if (value == null)
                {
                    value = _DefaultExceptionFormatter;
                }

                defaultExceptionFormatter = value;
            }
        }

        /// <summary>
        /// Resets the message formatters to the values from construction
        /// </summary>
        public static void Reset()
        {
            defaultMessageFormatter = _DefaultMessageFormatter;
            defaultExceptionFormatter = _DefaultExceptionFormatter;
        }

        private static string _DefaultMessageFormatter(string userMessage, LoggerName name, LogLevel level)
        {
            if (userMessage == null)
            {
                userMessage = string.Empty;
            }

            string date = Clock.UtcNow.ToString("s", CultureInfo.InvariantCulture);
            string thread = Thread.CurrentThread.Name ?? Messages.NoThread;
            string logger = name.ToString();
            string levelStr = level.ToString();

            float initialCapacity 
                = date.Length + 
                  thread.Length + 
                  logger.Length + 
                  levelStr.Length + 
                  userMessage.Length;

            // increase by 5% to cover overages
            initialCapacity *= 1.05F;

            return
                new StringBuilder((int)initialCapacity)
                        .Append(date)
                        .Append("|   |")
                        .Append(thread)
                        .Append('|')
                        .Append(logger)
                        .Append('|')
                        .Append(userMessage)
                        .ToString();
        }

        private static string _DefaultExceptionFormatter(Exception ex, LoggerName name, LogLevel level)
        {
            string userMessage = string.Empty;
            if (ex != null)
            {
                userMessage = ex.ToString();
            }

            string date = Clock.UtcNow.ToString("s", CultureInfo.InvariantCulture);
            string thread = Thread.CurrentThread.Name ?? Messages.NoThread;
            string logger = name.ToString();
            string levelStr = level.ToString();

            float initialCapacity
                = date.Length +
                  thread.Length +
                  logger.Length +
                  levelStr.Length +
                  userMessage.Length;

            // increase by 5% to cover overages
            initialCapacity *= 1.05F;

            return
                new StringBuilder((int)initialCapacity)
                        .Append(date)
                        .Append("|***|")
                        .Append(thread)
                        .Append('|')
                        .Append(logger)
                        .Append('|')
                        .Append(userMessage)
                        .ToString();
        }
    }
}